package io.renren.modules.work.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSONObject;
import io.renren.common.utils.*;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.work.dao.ScGoodsDao;
import io.renren.modules.work.dao.ScPurdtlDao;
import io.renren.modules.work.entity.*;
import io.renren.modules.work.service.*;
import io.renren.vo.ScConsumablesVo;
import io.renren.vo.ScProjectdtlVo;
import io.renren.vo.ScPurVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jfree.util.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import io.renren.modules.work.dao.ScPurDao;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


@Service("scPurService")
@Slf4j
public class ScPurServiceImpl extends ServiceImpl<ScPurDao, ScPurEntity> implements ScPurService {


    @Autowired
    private ScPurdtlService scPurdtlService;
    
    @Autowired
    private ScStockService scStockService;
    @Autowired
    private ScGoodsService scGoodsService;
    @Autowired
    private ScConsumablesService scConsumablesService;

    @Autowired
    private ScStocktranService scStocktranService;

    @Autowired
    private ScPurdtlDao scPurdtlDao;
    @Autowired
    private ScGoodsDao scGoodsDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<ScPurEntity> scPurEntityQueryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank((String) params.get("purno"))){
            scPurEntityQueryWrapper.eq("purno",params.get("purno"));
        }
        if(StringUtils.isNotBlank((String) params.get("purname"))){
            scPurEntityQueryWrapper.like("purname",params.get("purname"));
        }
        IPage<ScPurEntity> page = this.page(
                new Query<ScPurEntity>().getPage(params),
                scPurEntityQueryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public R commitProject(String params, SysUserEntity user) {
        log.info("调用保存采购单接口");
        log.info("{}:",params);
        //工程id
        String id = ConfigConstant.getId();

        ScPurVo scPurVo = JSONObject.parseObject(params, ScPurVo.class);
        //保存主单
        ScPurEntity scPurEntity = new ScPurEntity();
        scPurEntity.setPurid(id);
        scPurEntity.setPurname(scPurVo.getPurname());
        scPurEntity.setPurno(ConfigConstant.generatePurNo());
        scPurEntity.setCretime(new Date());
        scPurEntity.setPurtype(scPurVo.getPurtype());
        scPurEntity.setPurstatus(ConfigConstant.PURSTATUS_INITIAL);
        baseMapper.insert(scPurEntity);
        //保存细单
        for (ScPurdtlEntity scPurdtlEntity : scPurVo.getScpurdtl()) {
            scPurdtlEntity.setPurid(id);
            scPurdtlEntity.setPurdtlno(ConfigConstant.generatePurdtlNo());
            scPurdtlEntity.setPurdtlStatus(ConfigConstant.PURSTATUS_INITIAL);
            scPurdtlService.save(scPurdtlEntity);
        }

        log.info("保存细单完成");
        return R.ok();
    }

    /**
     * 确认收货，增加库存
     * @param purdtlids
     * @return
     */
    @Override
    public R confirmRg(String[] purdtlids) {
        if(purdtlids.length==0){
            return R.error();
        }

        for (String purdtlid : purdtlids) {
            //更新采购细单状态
            ScPurdtlEntity purdtl = scPurdtlService.getById(purdtlid);
            if(purdtl.getPurdtlStatus().equals(ConfigConstant.PURSTATUS_FINISH)){
                return R.error("该记录已验收");
            }
            purdtl.setPurdtlStatus(ConfigConstant.PURSTATUS_FINISH);
            scPurdtlService.updateById(purdtl);

        }
        //判断全部细单是否完成
        ScPurdtlEntity purdtl = scPurdtlService.getById(purdtlids[0]);
        QueryWrapper<ScPurdtlEntity> scPurdtlEntityQueryWrapper = new QueryWrapper<>();
        scPurdtlEntityQueryWrapper.eq("purid",purdtl.getPurid());
        scPurdtlEntityQueryWrapper.eq("purdtl_status",ConfigConstant.PURSTATUS_INITIAL);
        List<ScPurdtlEntity> scPurdtlList = scPurdtlService.list(scPurdtlEntityQueryWrapper);
        ScPurEntity scPurEntity = baseMapper.selectById(purdtl.getPurid());
        if(scPurdtlList.size()==0) {//全部完成
            scPurEntity.setPurstatus(ConfigConstant.PURSTATUS_FINISH);
            baseMapper.updateById(scPurEntity);
        }
            if(scPurEntity.getPurtype().equals(ConfigConstant.PURTYPE_NORMAL)){
                //正常采购，增加库存

                for (String purdtlid : purdtlids) {
                    ScPurdtlEntity scPurdtlEntity = scPurdtlService.getById(purdtlid);
                    ScStockEntity stock = null;
                    //查询库存
                    QueryWrapper<ScStockEntity> scStockEntityQueryWrapper = new QueryWrapper<>();
                    scStockEntityQueryWrapper.eq("goodsid",scPurdtlEntity.getGoodsid());
                    stock = scStockService.getOne(scStockEntityQueryWrapper);
                    if(stock!=null){//库存不为空，增加库存
                        BigDecimal newStockQty = new BigDecimal(stock.getGoodsqty()).add(scPurdtlEntity.getGoodsnum());
                        stock.setGoodsqty(newStockQty.doubleValue());
                        stock.setTotalPrice(stock.getCostPrice().multiply(new BigDecimal(stock.getGoodsqty())));
                        scStockService.updateById(stock);
                    }else{//库存为空，新增一条库存
                        stock = new ScStockEntity();
                        ScGoodsEntity goods = scGoodsService.getById(scPurdtlEntity.getGoodsid());
                        stock.setGoodsid(scPurdtlEntity.getGoodsid());
                        stock.setGoodsname(goods.getGoodsname());
                        stock.setGoodstype(goods.getGoodstype());
                        stock.setGoodsunit(goods.getGoodsunit());
                        stock.setGoodsqty(scPurdtlEntity.getGoodsnum().doubleValue());
                        stock.setCretime(new Date());
                        stock.setCostPrice(scPurdtlEntity.getSingleprice());
                        stock.setOfferPrice(scPurdtlEntity.getPrice());
                        stock.setTotalPrice(new BigDecimal(stock.getGoodsqty()).multiply(stock.getCostPrice()));
                        scStockService.save(stock);
                    }
                    //生成库存交易记录
                    ScStocktranEntity scStocktranEntity = new ScStocktranEntity();
                    scStocktranEntity.setStockid(stock.getStockid());
                    scStocktranEntity.setStocktrantype(ConfigConstant.STOCK_INT);
                    scStocktranEntity.setCretime(new Date());
                    scStocktranEntity.setNum(scPurdtlEntity.getGoodsnum());
                    scStocktranEntity.setGoodsname(stock.getGoodsname());
                    scStocktranEntity.setIfstore(ConfigConstant.IFSTORE_Y);
                    scStocktranEntity.setResourceid(scPurEntity.getPurid());
                    scStocktranEntity.setResourcetable("sc_pur");
                    scStocktranService.save(scStocktranEntity);
                }

            }else {
                //补货，不增加库存
                //生成库存交易记录
                for (String purdtlid : purdtlids) {
                    ScPurdtlEntity scPurdtlEntity = scPurdtlService.getById(purdtlid);
                    ScStocktranEntity scStocktranEntity = new ScStocktranEntity();
                    scStocktranEntity.setStockid(null);
                    scStocktranEntity.setStocktrantype(ConfigConstant.STOCK_INT);
                    scStocktranEntity.setCretime(new Date());
                    scStocktranEntity.setNum(scPurdtlEntity.getGoodsnum());
                    scStocktranEntity.setIfstore(ConfigConstant.IFSTORE_Y);
                    scStocktranEntity.setResourceid(scPurEntity.getPurid());
                    scStocktranEntity.setResourcetable("sc_pur");
                    scStocktranService.save(scStocktranEntity);
                }

            }



        return R.ok();
    }

    @Override
    @Transactional
    public R updatePur(String params) {
        ScPurVo scPurVo = JSONObject.parseObject(params, ScPurVo.class);
        //更新主单
        ScPurEntity scPurEntity = baseMapper.selectById(scPurVo.getPurid());
        scPurEntity.setPurname(scPurVo.getPurname());
        scPurEntity.setMemo(scPurVo.getMemo());
        baseMapper.updateById(scPurEntity);
        //更新细单
        List<ScPurdtlEntity> scpurdtl = scPurVo.getScpurdtl();
        List<ScPurdtlEntity> collect = scpurdtl.stream().filter(p -> StringUtils.isNotBlank(p.getPurdtlid())).collect(Collectors.toList());
        List<String> ids = new ArrayList<>();
        for (ScPurdtlEntity scPurdtlEntity : collect) {
            ids.add(scPurdtlEntity.getPurdtlid());
        }
        //删除细单
        QueryWrapper<ScPurdtlEntity> scPurdtlEntityQueryWrapper = new QueryWrapper<>();
        scPurdtlEntityQueryWrapper.eq("purid",scPurVo.getPurid());
        scPurdtlEntityQueryWrapper.ne("purdtlid",ids);
        scPurdtlService.remove(scPurdtlEntityQueryWrapper);
        for (ScPurdtlEntity scPurdtlEntity : scpurdtl) {
            if(StringUtils.isBlank(scPurdtlEntity.getPurdtlno())){
                scPurdtlEntity.setPurdtlno(ConfigConstant.generatePurdtlNo());
            }
            scPurdtlEntity.setPurid(scPurVo.getPurid());
            scPurdtlService.saveOrUpdate(scPurdtlEntity);
        }
        return R.ok();
    }

    @Override
    @Transactional
    public void generatePur(String consumablesid) {
        Boolean needPur = false; //是否需要生成补货单
        String purId = ConfigConstant.getId();
        ScPurEntity scPurEntity = new ScPurEntity();
        scPurEntity.setPurid(purId);
        scPurEntity.setPurno(ConfigConstant.generatePurNo());
        scPurEntity.setMemo("自动生成补货单");
        scPurEntity.setPurstatus(ConfigConstant.PURSTATUS_INITIAL);
        scPurEntity.setPurtype(ConfigConstant.PURTYPE_SUPPLY);
        Date date = new Date();
        scPurEntity.setPurname("补货单"+date.getTime());
        scPurEntity.setCretime(date);

        BigDecimal need = new BigDecimal("0");
        ScConsumablesEntity scConsumablesEntity = scConsumablesService.getById(consumablesid);
        if(scConsumablesEntity!=null){
                if(scConsumablesEntity.getGoodsid()!=null){
                    QueryWrapper<ScStockEntity> scStockEntityQueryWrapper = new QueryWrapper<>();
                    scStockEntityQueryWrapper.eq("goodsid",scConsumablesEntity.getGoodsid());
                    ScStockEntity stock = scStockService.getOne(scStockEntityQueryWrapper);

                    if(stock!=null){
                        if(new BigDecimal(stock.getGoodsqty()).compareTo(scConsumablesEntity.getNum())>=0){
                            //库存充足
                            BigDecimal left = new BigDecimal(stock.getGoodsqty()).subtract(scConsumablesEntity.getNum());//剩余
                            stock.setGoodsqty(left.doubleValue());
                            stock.setTotalPrice(stock.getCostPrice().multiply(new BigDecimal(stock.getGoodsqty())));
                            scStockService.updateById(stock);
                        }else {
                            needPur = true;
                            need = scConsumablesEntity.getNum().subtract(new BigDecimal(stock.getGoodsqty()));//需补货数量
                            stock.setGoodsqty(new Double(0));
                            scStockService.updateById(stock);


                        }
                    }else{
                        needPur = true;
                        need = scConsumablesEntity.getNum();
                    }

                }

        }
        if(needPur){
            ScPurdtlEntity scPurdtlEntity = new ScPurdtlEntity();
            scPurdtlEntity.setPurid(purId);
            scPurdtlEntity.setPurdtlno(ConfigConstant.generatePurdtlNo());
            scPurdtlEntity.setGoodsname(scConsumablesEntity.getGoodsname());
            scPurdtlEntity.setGoodsid(scConsumablesEntity.getGoodsid());
            scPurdtlEntity.setGoodsunit(scConsumablesEntity.getGoodsunit());
            scPurdtlEntity.setGoodsnum(need);
            scPurdtlEntity.setSingleprice(scConsumablesEntity.getSingleprice());
            BigDecimal price = scConsumablesEntity.getSingleprice().multiply(scConsumablesEntity.getNum());
            scPurdtlEntity.setPrice(price);
            scPurdtlService.save(scPurdtlEntity);

            baseMapper.insert(scPurEntity);
        }
    }

    @Override
    public R bindPur(String purid) {
        QueryWrapper<ScPurdtlEntity> scPurdtlEntityQueryWrapper = new QueryWrapper<>();
        scPurdtlEntityQueryWrapper.eq("purid",purid);
        List<ScPurdtlEntity> list = scPurdtlService.list(scPurdtlEntityQueryWrapper);

        ArrayList<ScConsumablesVo> goodslist = new ArrayList<>();
        if(!list.isEmpty()){
            for (ScPurdtlEntity scPurdtlEntity : list) {
                ScConsumablesVo goods = new ScConsumablesVo();
                goods.setGoodsname(scPurdtlEntity.getGoodsname());
                goods.setGoodsunit(scPurdtlEntity.getGoodsunit());
                goods.setNum(scPurdtlEntity.getGoodsnum());
                goods.setSingleprice(scPurdtlEntity.getSingleprice());
                goods.setIfstore(true);
                goodslist.add(goods);
            }
        }
        return R.ok().put("data",goodslist);
    }
    @Transactional
    @Override
    public R importExcel(MultipartFile file) throws IOException {
        ExcelReader excelReader = null;
        InputStream inputStream = null;

        try {
            inputStream = file.getInputStream();
            excelReader = EasyExcel.read(inputStream, ExcelData_Pur.class,
                    new ExcelListener_Pur(baseMapper,scPurdtlDao,scGoodsDao)).build();
            ReadSheet readSheet = EasyExcel.readSheet(0).build();
            excelReader.read(readSheet);

        } catch (IOException e) {
            e.printStackTrace();
            Log.error("import excel to db failed!",e);
        } finally {
            inputStream.close();
            // 这里一定别忘记关闭，读的时候会创建临时文件
            if (excelReader != null) {
                excelReader.finish();
            }
        }
        Log.info("import excel to db successfully!");
        return R.ok();
    }

}